#ifndef TABBPORO_H_
#define TABBPORO_H_

#include "tporo.h"
#include "tvectorporo.h"
#include "tcolaabbporo.h"

/** \file taabbporo.h
* \brief .h del arbol binario
* Definicion de las clases del arbol binario
*/

class TECAP;
class TNodoABB;
class TColaABBPoro;

/** \class TABBPoro
* \brief Clase TABBPoro
* Clase completa para construir TABBPoro
*/
class TABBPoro
{
    friend class TNodoABB;
    friend class TECAP;
    friend class TColaABBPoro;

    private:
        /** \brief nodo
        *	Variable que representa el nodo
        */
        TNodoABB *nodo;
        /** \brief BuscarMayor
        * Busca el mayor de los poros en arbol
        * \return Devuelve el mayor poro
	*/
	TPoro BuscarMayor() const;
        /** \brief InordenAux
        * Auxiliar para el recorrido en inorden
        * \param UP vector
        * \param pos entero
	*/
	void InordenAux(TVectorPoro &, int &) const;
        /** \brief PreordenAux
        * Auxiliar para el recorrido en inorden
        * \param UP vector
        * \param pos entero
	*/
        void PreordenAux(TVectorPoro &, int &) const;
        /** \brief PostordenAux
        * Auxiliar para el recorrido en inorden
        * \param UP vector
        * \param pos entero
	*/
        void PostordenAux(TVectorPoro &, int &) const;

    public:
        /** \brief Constructor por defecto
	* Construye un objeto TABBPoro con valores inicializados
	*/
        TABBPoro():nodo(0){};
        /** \brief Constructor de copia
        * Crea una copia del objeto que recibe
        * \param poro Poro del que copiar
        */
        TABBPoro(const TABBPoro &);
        /** \brief Destructor
        * Destruye el objeto liberando memoria de las variables
        */
        ~TABBPoro();
        /** \brief Sobrecarga del operador asignación
        * Copia los valores de un objeto a otro
        * \param aaa ABB del que copiar
        * \return Objeto copiado
        */
        TABBPoro & operator=(const TABBPoro &);
        /** \brief Sobrecarga del operador igualdad
        * Compara los dos objetos y devuelve un bool
        * \param de ABB a comparar
        * \return Devuelve si es verdadero o falso
        */
        bool operator==(const TABBPoro &) const;
        /** \brief EsVacio()
        * Mira si el ABB es vacio o no
        * \return Devuelve si es verdadero o falso
        */
        bool EsVacio() const;
        /** \brief Insertar
        * Inserta un poro en el arbol
        * \param p poro
        * \return Devuelve si es verdadero o falso
        */
        bool Insertar(const TPoro &);
        /** \brief Borrar
        * Borrar un poro del arbol
        * \param p poro
        * \return Devuelve si es verdadero o falso
        */
        bool Borrar(const TPoro &);
        /** \brief Buscar
        * Busca un poro en el arbol
        * \param p poro
        * \return Devuelve si es verdadero o falso
        */
        bool Buscar(const TPoro &) const;
        /** \brief Raiz
        * Devuelve el poro que ocupa la posicion de la raiz
        * \return Devuelve la raiz
        */
        TPoro Raiz() const;
        /** \brief Altura
        * Devuelve la altura del arbol
        * \return poro
        */
        int Altura() const;
        /** \brief Nodos
        * Devuelve la cantidad de nodos del arbol
        * \return entero
        */
        int Nodos() const;
        /** \brief NodosHoja
        * Devuelve la cantidad de nodos hoja del arbol
        * \return entero
        */
        int NodosHoja() const;
        /** \brief Sobrecarga del operador suma
        * Hace la suma de dos arboles
        * \param aaa Arbol a sumar
        * \return Devuelve la suma
        */
        TABBPoro operator+(const TABBPoro &) const;
        /** \brief Sobrecarga del operador resta
        * Hace la resta de dos arboles
        * \param aaa Arbol a restar
        * \return Devuelve la resta
        */
        TABBPoro operator-(TABBPoro &) const;
        /** \brief Inorden
        * Hace el recorrido inorden
        * \return Devuelve el recorrido en un vector
        */
        TVectorPoro Inorden() const;
        /** \brief Preorden
        * Hace el recorrido preorden
        * \return Devuelve el recorrido en un vector
        */
        TVectorPoro Preorden() const;
        /** \brief Postorden
        * Hace el recorrido postorden
        * \return Devuelve el recorrido en un vector
        */
        TVectorPoro Postorden()const ;
        /** \brief Niveles
        * Hace el recorrido por niveles
        * \return Devuelve el recorrido en un vector
        */
        TVectorPoro Niveles() const;
        /** \brief Sobrecarga del operador SALIDA
        * Imprime el contenido del objeto
        * \param os Tipo ostream&
        * \param arbol Objeto TABBPoro
        * \return ostream&
        */
        friend ostream & operator<<(ostream &, const TABBPoro &);
        friend ostream & operator<<(ostream &, const TColaABBPoro &);
};

class TNodoABB
{
    friend class TABBPoro;
    friend class TECAP;
    friend class TColaABBPoro;
 
    private:
        /** \brief item
        *	Variable que representa el item del nodo
        */
        TPoro item;
        /** \brief iz
        *	Variable que representa el hijo izquierdo
        */
        TABBPoro iz;
        /** \brief arbol
        *	Variable que representa el hijo derecho
        */
        TABBPoro de;

    public:
        /** \brief Constructor por defecto
	* Construye un objeto TABBPoro con valores inicializados
	*/
        TNodoABB(){};
        /** \brief Constructor de copia
        * Crea una copia del objeto que recibe
        * \param nodo Nodo del que copiar
        */
        TNodoABB(const TNodoABB &);
        /** \brief Destructor
        * Destruye el objeto liberando memoria de las variables
        */
        ~TNodoABB();
        /** \brief Sobrecarga del operador asignación
        * Copia los valores de un objeto a otro
        * \param nodo nodo del que copiar
        * \return Objeto copiado
        */
        TNodoABB & operator=(const TNodoABB &);
        friend ostream & operator<<(ostream &, const TABBPoro &);
        friend ostream & operator<<(ostream &, const TColaABBPoro &);
};



#endif /* TABBPORO_H_ */
